home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file is part of the portable Forth environment written in ANSI C.
- * Copyright (C) 1995 Dirk Uwe Zoller
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This file is version 0.9.13 of 17-July-95
- * Check for the latest version of this package via anonymous ftp at
- * roxi.rz.fht-mannheim.de:/pub/languages/forth/pfe-VERSION.tar.gz
- * or sunsite.unc.edu:/pub/languages/forth/pfe-VERSION.tar.gz
- * or ftp.cygnus.com:/pub/forth/pfe-VERSION.tar.gz
- *
- * Please direct any comments via internet to
- * duz@roxi.rz.fht-mannheim.de.
- * Thank You.
- */
- /*
- * double.c --- The Optional Double Number Word Set
- * (duz 16Jul93)
- */
-
- #include "forth.h"
- #include "support.h"
- #include "dblsub.h"
- #include "compiler.h"
-
- #define DSP ((dCell *)sp)
- #define UDP ((udCell *)sp)
-
- void
- two_constant_runtime (void)
- {
- *--sp = PFA[1];
- *--sp = PFA[0];
- }
-
- Code (two_constant)
- {
- header (two_constant_runtime, 0);
- COMMA (*sp++);
- COMMA (*sp++);
- }
-
- code (two_literal_execution)
- {
- Cell h;
-
- POP (Cell, ip, h);
- POP (Cell, ip, *--sp);
- *--sp = h;
- }
-
- Code (two_literal)
- {
- if (STATE)
- {
- compile1 ();
- COMMA (DSP->hi);
- COMMA (DSP->lo);
- sp += 2;
- }
- }
- COMPILES (two_literal, two_literal_execution,
- SKIPS_DCELL, DEFAULT_STYLE);
-
- Code (two_variable)
- {
- header (create_runtime, 0);
- COMMA (0);
- COMMA (0);
- }
-
- Code (d_plus)
- {
- dadd (&DSP[1], &DSP[0]);
- sp += 2;
- }
-
- Code (d_minus)
- {
- dsub (&DSP[1], &DSP[0]);
- sp += 2;
- }
-
- code (d_dot)
- {
- *--sp = 0;
- d_dot_r_ ();
- space_ ();
- }
-
- code (d_dot_r)
- {
- Cell w = *sp++;
- int sign;
-
- if (*sp < 0)
- sign = 1, dnegate (&DSP[0]);
- else
- sign = 0;
- less_number_sign_ ();
- number_sign_s_ ();
- if (sign)
- hold ('-');
- number_sign_greater_ ();
- spaces (w - *sp);
- type_ ();
- }
-
- Code (d_zero_less)
- {
- sp[1] = FLAG (sp[0] < 0);
- sp++;
- }
-
- Code (d_zero_equals)
- {
- sp[1] = FLAG (sp[0] == 0 && sp[1] == 0);
- sp++;
- }
-
- Code (d_two_star)
- {
- dasl ((dCell *) &sp[0], 1);
- }
-
- Code (d_two_slash)
- {
- dasr ((dCell *) &sp[0], 1);
- }
-
- Code (d_less_than)
- {
- sp[3] = FLAG (dless (&DSP[1], &DSP[0]));
- sp += 3;
- }
-
- Code (d_to_s)
- {
- sp++;
- }
-
- Code (d_equals)
- {
- sp[3] = FLAG (sp[2] == sp[0] && sp[3] == sp[1]);
- sp += 3;
- }
-
- Code (d_abs)
- {
- if (*sp < 0)
- dnegate (&DSP[0]);
- }
-
- Code (d_max)
- {
- if (dless (&DSP[1], &DSP[0]))
- DSP[1] = DSP[0];
- sp += 2;
- }
-
- Code (d_min)
- {
- if (dless (&DSP[0], &DSP[1]))
- DSP[1] = DSP[0];
- sp += 2;
- }
-
- Code (d_negate)
- {
- dnegate (&DSP[0]);
- }
-
- Code (m_star_slash)
- {
- udCell lo, hi;
- Cell p, q;
- udiv_t r1, r2;
- int sign = 0;
-
- if ((q = *sp++) < 0)
- q = -q, sign ^= 1;
- if ((p = *sp++) < 0)
- p = -p, sign ^= 1;
- if (*sp < 0)
- dnegate (&DSP[0]), sign ^= 1;
- hi = ummul (sp[0], p);
- lo = ummul (sp[1], p);
- madd ((dCell *) &hi, lo.hi);
- r1 = umdiv (hi, q);
- lo.hi = r1.rem;
- r2 = umdiv (lo, q);
- sp[0] = r1.quot;
- sp[1] = r2.quot;
- if (sign)
- dnegate (&DSP[0]);
- }
-
- Code (m_plus)
- {
- madd ((dCell *) &sp[1], sp[0]);
- sp++;
- }
-
- Code (two_rot)
- {
- Cell h;
-
- h = sp[4];
- sp[4] = sp[2];
- sp[2] = sp[0];
- sp[0] = h;
- h = sp[5];
- sp[5] = sp[3];
- sp[3] = sp[1];
- sp[1] = h;
- }
-
- Code (d_u_less)
- {
- sp[3] = FLAG (duless (&UDP[1], &UDP[0]));
- sp += 3;
- }
-
- /* *INDENT-OFF* */
- LISTWORDS (double) =
- {
- CO ("2CONSTANT", two_constant),
- CS ("2LITERAL", two_literal),
- CO ("2VARIABLE", two_variable),
- CO ("D+", d_plus),
- CO ("D-", d_minus),
- CO ("D.", d_dot),
- CO ("D.R", d_dot_r),
- CO ("D0<", d_zero_less),
- CO ("D0=", d_zero_equals),
- CO ("D2*", d_two_star),
- CO ("D2/", d_two_slash),
- CO ("D<", d_less_than),
- CO ("D=", d_equals),
- CO ("D>S", d_to_s),
- CO ("DABS", d_abs),
- CO ("DMAX", d_max),
- CO ("DMIN", d_min),
- CO ("DNEGATE", d_negate),
- CO ("M*/", m_star_slash),
- CO ("M+", m_plus),
- CO ("2ROT", two_rot),
- CO ("DU<", d_u_less)
- };
- COUNTWORDS (double, "Double number + extensions");
-